#include "stdafx.h"
#include "VaoMesh.h"


VaoMesh::VaoMesh(GLenum bufUsage)
{
	m_vao = m_vboVertex = m_vboIndices = 0;
	m_bufUsage = bufUsage;
	m_indicesElementSize = 0;
	//m_vboDrawInstanceData = 0;
}

VaoMesh::~VaoMesh()
{
	if (m_vao) glDeleteVertexArrays(1, &m_vao);
	if (m_vboVertex) glDeleteBuffers(1, &m_vboVertex);
	if (m_vboIndices) glDeleteBuffers(1, &m_vboIndices);
}

void VaoMesh::GenVaoVbo(void *verts, int vertCount, int vertDataSize, VertexAttribPointerParam *params, int paramCount, void *indices, int indicesCount, GLenum indicesType)
{
	m_indicesType = indicesType;
	if (indices)
	{
		switch (indicesType)
		{
		case GL_UNSIGNED_BYTE:
			m_indicesElementSize = 1;
			break;
		case GL_UNSIGNED_SHORT:
			m_indicesElementSize = 2;
			break;
		case GL_UNSIGNED_INT:
			m_indicesElementSize = 4;
			break;
		default:
			_ASSERT(0);
			return;
		}
	}
	_ASSERT(!m_vao);
	glGenVertexArrays(1, &m_vao);
	glBindVertexArray(m_vao);

	glGenBuffers(1, &m_vboVertex);
	glBindBuffer(GL_ARRAY_BUFFER, m_vboVertex);
	glBufferData(GL_ARRAY_BUFFER, vertDataSize * vertCount, verts, m_bufUsage);

	for (int i = 0; i < paramCount; i++)
	{
		params[i].VertexAttribPointer();
		//glVertexAttribPointer(params[i].index, params[i].size, params[i].type, params[i].normalized, params[i].stride, params[i].pointer);
		glEnableVertexAttribArray(params[i].index);
	}

	//if (m_vboDrawInstanceData)
	//{
	//	glBindBuffer(GL_ARRAY_BUFFER, m_vboDrawInstanceData->GetVbo());
	//	for (auto &param : m_vboDrawInstanceData->GetAttribParams())
	//	{
	//		param.VertexAttribPointer();
	//		//glVertexAttribPointer(param.index, param.size, param.type, param.normalized, param.stride, param.pointer);
	//		glVertexAttribDivisor(param.index, 1);
	//		glEnableVertexAttribArray(param.index);
	//	}
	//}

	glBindBuffer(GL_ARRAY_BUFFER, 0);

	if (indices)
	{
		glGenBuffers(1, &m_vboIndices);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vboIndices);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indicesElementSize*indicesCount, indices, m_bufUsage);
	}
	glBindVertexArray(0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

GLuint VaoMesh::GetVao()
{
	return m_vao;
}

void VaoMesh::UpdateVbo(int offset, int size, void *data)
{
	glBindBuffer(GL_ARRAY_BUFFER, m_vboVertex);
	glBufferSubData(GL_ARRAY_BUFFER, offset, size, data);
}

GLenum VaoMesh::GetIndicesType()
{
	return m_indicesType;
}

int VaoMesh::GetIndicesElementSize()
{
	return m_indicesElementSize;
}

//void VaoMesh::SetVboDrawInstanceData(VboData *vboData)
//{
//	m_vboDrawInstanceData = vboData;
//}
//
//VboData *VaoMesh::GetVboDrawInstanceData()
//{
//	return m_vboDrawInstanceData;
//}

VaoMesh::SubMesh *VaoMesh::GetSubMesh(int *outCount)
{
	*outCount = m_subMeshs.size();
	return &m_subMeshs[0];
}